package com.cssl.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cssl.api.OrderApi;
import com.cssl.dto.UserCreateDTO;
import com.cssl.dto.UserRechargeDTO;
import com.cssl.entity.TopUp;
import com.cssl.entity.User;
import com.cssl.exception.BusinessException;
import com.cssl.mapper.UserMapper;
import com.cssl.service.TopUpService;
import com.cssl.service.UserService;
import com.cssl.util.UtilEncryption;
import io.seata.spring.annotation.GlobalTransactional;
import org.bouncycastle.jcajce.provider.digest.MD5;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ConcurrentModificationException;
import java.util.List;

@Service
@Transactional
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    @Autowired
    private OrderApi orderApi;
    @Autowired
    private TopUpService tus;

    // 定义常量
    private static final String UPDATE_STATUS_FAILED = "修改订单状态失败";

    @Override
    public Boolean createUser(UserCreateDTO userDto) throws BusinessException {
        // 判断用户是否存在
        if(super.exists(new QueryWrapper<User>().eq("phone",userDto.getPhone()))) {
            //用户已存在
            throw new BusinessException("用户已存在！");
        }
        //加密
        String decryptedText = "";
        try {
            decryptedText = UtilEncryption.encrypt(userDto.getCipher());
        } catch (Exception e) {
            System.out.println("加密失败");
            throw new RuntimeException(e);
        }
        //添加用户
        User user = new User(
                decryptedText,
                userDto.getName(),
                userDto.getBalance(),
                0,0,0,
                LocalDateTime.now(),
                userDto.getId_number(),
                userDto.getPhone()

        );
        return super.baseMapper.insert(user) > 0;
    }

    /**
     * 余额操作 （带乐观锁） 充值
     *@return
     */
    @Override
    public BigDecimal recharge(UserRechargeDTO urDto) {
        System.out.println("**************:"+urDto);
        User user = super.baseMapper.selectById(urDto.getNumber());
        BigDecimal newBalance = user.getBalance().add(urDto.getAmount());

        int result = super.baseMapper.update(user,
                new UpdateWrapper<User>()
                        .set("balance", newBalance)
                        .set("version", user.getVersion() + 1)
                        .eq("number", urDto.getNumber())
                        .eq("version", user.getVersion())
        );

        if (result == 0) {
            throw new ConcurrentModificationException("余额更新冲突，请重试");
        }

        //添加充值信息
        boolean recharge = tus.save(new TopUp(
                urDto.getEp_id(),
                urDto.getNumber(),
                urDto.getAmount(),
                LocalDateTime.now(),
                urDto.getText()
        ));

        if(!recharge)
            throw new ConcurrentModificationException("充值失败");

        return newBalance;
    }

    /**
     * 扣减余额
     * @param userId
     * @param amount
     * @return
     */
    @Override
    public BigDecimal deductionMoney(Integer userId, BigDecimal amount) {
        // 查询用户当前信息
        User user = super.baseMapper.selectById(userId);

        if (user == null) {
            throw new IllegalArgumentException("用户不存在");
        }

        // 检查余额是否充足
        if (user.getBalance().compareTo(amount) < 0) {
            throw new IllegalArgumentException("余额不足");
        }

        // 计算新余额
        BigDecimal newBalance = user.getBalance().subtract(amount);

        // 更新用户余额和版本号
        int result = super.baseMapper.update(null,
                new UpdateWrapper<User>()
                        .set("balance", newBalance)
                        .set("version", user.getVersion() + 1)
                        .eq("number", userId)
                        .eq("version", user.getVersion())
        );

        // 检查更新是否成功
        if (result == 0) {
            throw new ConcurrentModificationException("余额更新冲突，请重试");
        }

        return newBalance;
    }

    /**
     * 扣减余额 （购买商品使用）
     * @param userId
     * @param amount
     * @param po_id
     * @return
     */
    @GlobalTransactional(name="orderProduct",rollbackFor = Exception.class)
    @Override
    public BigDecimal deductionM(Integer userId, BigDecimal amount, String po_id) {
        // 查询用户当前信息
        User user = super.baseMapper.selectById(userId);

        if (user == null) {
            throw new IllegalArgumentException("用户不存在");
        }

        // 检查余额是否充足
        if (user.getBalance().compareTo(amount) < 0) {
            throw new IllegalArgumentException("余额不足");
        }

        // 计算新余额
        BigDecimal newBalance = user.getBalance().subtract(amount);

        // 更新用户余额和版本号
        int result = super.baseMapper.update(null,
                new UpdateWrapper<User>()
                        .set("balance", newBalance)
                        .set("version", user.getVersion() + 1)
                        .eq("number", userId)
                        .eq("version", user.getVersion())
        );

        // 检查更新是否成功
        if (result == 0) {
            throw new ConcurrentModificationException("余额更新冲突，请重试");
        }
        //同时修改该订单状态
        String status = orderApi.updateStatus(po_id);
        if(UPDATE_STATUS_FAILED.equals(status) || status == null){
            throw new ConcurrentModificationException("修改状态失败，请重试");
        }
        return newBalance;
    }

    /**
     * 查询当天注册的新用户
     * @return
     */
    @Override
    public int findNewUser() {
        return super.baseMapper.findNewUser();
    }

    /**
     * 查询前天注册的新用户
     * @return
     */
    @Override
    public int findNewUser_yd() {
        return super.baseMapper.findNewUser_yd();
    }

    /**
     * 查询所有用户的当前状态
     * @return
     *//*
    @Override
    public List<User> findUserStatus(){
        //查询所有在线的用户
        List<Integer>

        return null;
    }*/
}
